package cn.stylefeng.guns.sys.core.filter.security;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.guns.core.consts.CommonConstant;
import cn.stylefeng.guns.core.exception.enums.AuthExceptionEnum;
import cn.stylefeng.guns.core.util.HttpServletUtil;
import cn.stylefeng.guns.core.util.IpAddressUtil;
import cn.stylefeng.guns.core.util.ResponseUtil;
import cn.stylefeng.guns.sys.core.cache.RedisCache;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * 图片验证码filter,这个过滤类在token过滤类 {@link JwtAuthenticationTokenFilter} 之前, 主要校验验证码信息
 *
 * @author zhushengjie
 * @date 2022-09-14
 */
@Component
public class CaptchaValidateFilter extends OncePerRequestFilter {

    private static final Logger LOGGER = org.apache.logging.log4j.LogManager.getLogger(OncePerRequestFilter.class);

    /**
     * 登录url
     */
    private final String LOGIN_URL = "/login";

    @Autowired
    private RedisCache redisCache;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
        String method = httpServletRequest.getMethod();
        String code = httpServletRequest.getParameter("code");
        String locale = httpServletRequest.getParameter("locale");
        HttpServletRequest request = HttpServletUtil.getRequest();
        String ip = "";
        if (ObjectUtil.isNotNull(request)) {
            ip = IpAddressUtil.getIp(request);
        }
        String redisCaptchaKey = CommonConstant.CAPTCHA_CODE + "_" + ip;

        //登录接口 post请求才校验验证码
        if (StrUtil.equals(LOGIN_URL, httpServletRequest.getRequestURI()) && HttpMethod.POST.matches(method) && !"passwordFreeLogin".equals(code)) {
            //验证码为空
            if (StrUtil.isBlank(code)) {
                if(StrUtil.isNotBlank(locale) && locale.equals("en")) {
                    ResponseUtil.responseExceptionError(httpServletResponse, AuthExceptionEnum.CAPTCHA_NULL_EN.getCode(), AuthExceptionEnum.CAPTCHA_NULL_EN.getMessage(), "");
                } else {
                    ResponseUtil.responseExceptionError(httpServletResponse, AuthExceptionEnum.CAPTCHA_NULL.getCode(), AuthExceptionEnum.CAPTCHA_NULL.getMessage(), "");
                }
                return;
            }

            String redisCaptcha = redisCache.get(redisCaptchaKey);
            if (StrUtil.isBlank(redisCaptcha)) {
                if(StrUtil.isNotBlank(locale) && locale.equals("en")) {
                    ResponseUtil.responseExceptionError(httpServletResponse, AuthExceptionEnum.CAPTCHA_EXP_TIME_EN.getCode(), AuthExceptionEnum.CAPTCHA_EXP_TIME_EN.getMessage(), "");
                } else {
                    ResponseUtil.responseExceptionError(httpServletResponse, AuthExceptionEnum.CAPTCHA_EXP_TIME.getCode(), AuthExceptionEnum.CAPTCHA_EXP_TIME.getMessage(), "");
                }
                return;
            }
            if (!StrUtil.equals(code, redisCaptcha)) {
                LOGGER.info("**********httpServletRequest.getRequestURI():" + httpServletRequest.getRequestURI());
                LOGGER.info("**********code:" + code + "**************redisCaptcha:" + redisCaptcha);
                if(StrUtil.isNotBlank(locale) && locale.equals("en")) {
                    ResponseUtil.responseExceptionError(httpServletResponse, AuthExceptionEnum.CAPTCHA_VALIDATE_ERROR_EN.getCode(), AuthExceptionEnum.CAPTCHA_VALIDATE_ERROR_EN.getMessage(), "");
                } else {
                    ResponseUtil.responseExceptionError(httpServletResponse, AuthExceptionEnum.CAPTCHA_VALIDATE_ERROR.getCode(), AuthExceptionEnum.CAPTCHA_VALIDATE_ERROR.getMessage(), "");
                }
                return;
            }
            //安全要求验证码验证通过后删除该验证码
            redisCache.remove(redisCaptchaKey);
        }

        //验证码校验通过, 放行请求
        filterChain.doFilter(httpServletRequest, httpServletResponse);
    }
}
